package com.atguigu.paymentdemo.controller;

import com.atguigu.paymentdemo.service.WxPayService;
import com.atguigu.paymentdemo.util.HttpUtils;
import com.atguigu.paymentdemo.util.WechatPay2ValidatorForRequest;
import com.atguigu.paymentdemo.vo.R;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author longge
 * @Title:
 * @Description:
 * @date 2023/2/5 13:54
 */
@Api(tags = "网站微信支付API")
@Slf4j
@RestController
@RequestMapping("/api/wx-pay")
public class WxPayController {

    @Autowired
    private WxPayService wxPayService;

    @Autowired
    private Verifier verifier;

    @ApiOperation("调用统一下单API，生成支付二维码")
    @PostMapping("/native/{productId}")
    public R nativePay(@PathVariable Long productId) throws IOException {
        log.info("发起支付请求");

        //获取支付二维码和订单号
        Map<String, Object> map = wxPayService.nativePay(productId);
        return R.ok().setData(map);
    }

    @ApiOperation("回调地址")
    @PostMapping("native/notify")
    public String nativeNotify(HttpServletRequest request, HttpServletResponse response){
        Gson gson = new Gson();
        HashMap<String, String> result = new HashMap<>();

        //处理通知参数
        try {
            String body = HttpUtils.readData(request);
            log.info("支付通知内容：{}",body);
            HashMap<String,Object> bodyMap = gson.fromJson(body, HashMap.class);

            //验签
            WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest =
                    new WechatPay2ValidatorForRequest(verifier, body, (String) bodyMap.get("id"));
            if (!wechatPay2ValidatorForRequest.validate(request)){
                result.put("code","FAIL");
                result.put("message","验签失败");
                response.setStatus(500);
                return gson.toJson(result);
            }
            log.info("验签成功");

            //处理订单
            wxPayService.processOrder(bodyMap);

            result.put("code","SUCCESS");
            result.put("message","");
            response.setStatus(200);
            return gson.toJson(result);
        } catch (Exception e) {
            e.printStackTrace();
            result.put("code","FAIL");
            result.put("message","失败");
            response.setStatus(500);
            return gson.toJson(result);
        }
    }


    @ApiOperation("退款结果通知")
    @PostMapping("/refunds/notify")
    public String refundsNotify(HttpServletRequest request, HttpServletResponse response){
        Gson gson = new Gson();
        HashMap<String, String> result = new HashMap<>();

        try {
            String bodyString = HttpUtils.readData(request);
            log.info("退款通知内容：{}",bodyString);
            HashMap<String,Object> bodyMap = gson.fromJson(bodyString, HashMap.class);

            //验签
            WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest =
                    new WechatPay2ValidatorForRequest(verifier, bodyString, (String) bodyMap.get("id"));
            if (!wechatPay2ValidatorForRequest.validate(request)){
                result.put("code","FAIL");
                result.put("message","验签失败");
                response.setStatus(500);
                return gson.toJson(result);
            }
            log.info("验签成功");

            wxPayService.processRefund(bodyMap);
            result.put("code","SUCCESS");
            result.put("message","");
            response.setStatus(200);
            return gson.toJson(result);
        } catch (Exception e) {
            e.printStackTrace();
            result.put("code","FAIL");
            result.put("message","失败");
            response.setStatus(500);
            return gson.toJson(result);
        }
    }


    @ApiOperation("取消订单")
    @PostMapping("/cancel/{orderNo}")
    public R cancel(@PathVariable("orderNo") String orderNo) throws IOException {
        log.info("取消订单");
        wxPayService.cancelOrder(orderNo);
        return R.ok().setMessage("订单已取消");
    }


    @ApiOperation("查询订单")
    @GetMapping("/query/{orderNo}")
    public R queryOrder(@PathVariable("orderNo") String orderNo) throws IOException {
        log.info("查询订单");
        String result = wxPayService.queryOrder(orderNo);
        return R.ok().setMessage("查询成功").data("result",result);
    }


    @ApiOperation("申请退款")
    @PostMapping("/refunds/{orderNo}/{reason}")
    public R refunds(@PathVariable("orderNo") String orderNo,@PathVariable("reason") String reason) throws IOException {
        log.info("申请退款");
        wxPayService.refund(orderNo,reason);
        return R.ok();
    }

    @ApiOperation("查询退款")
    @GetMapping("/query-refund/{refundNo}")
    public R queryRefund(@PathVariable("refundNo") String refundNo) throws IOException {
        log.info("查询退款");
        String result = wxPayService.queryRefund(refundNo);
        return R.ok().data("result",result);
    }

    @ApiOperation("查询账单")
    @GetMapping("/querybill/{billDate}/{type}")
    public R queryTradeBill(@PathVariable("billDate") String billDate,@PathVariable("type") String type) throws IOException {
        log.info("获取账单url");
        String downloadUrl = wxPayService.queryBill(billDate,type);
        return R.ok().setMessage("获取账单url成功").data("downloadUrl",downloadUrl);
    }

    @ApiOperation("下载账单")
    @GetMapping("/downloadbill/{billDate}/{type}")
    public R downloadBill(@PathVariable("billDate") String billDate,@PathVariable("type") String type) throws IOException {
        log.info("下载账单");
        String result = wxPayService.downloadBill(billDate,type);
        return R.ok().data("result",result);
    }
}
